import { MapControls } from 'three/addons/controls/MapControls.js'
import * as Cesium from 'cesium'
import * as THREE from 'three'

export class MyMapControls extends MapControls {
    static instance = null
    static map = new Map()

    static getLocalUpFromCartesian(cartesian3) {
        //  4x4线性变换矩阵中8,9,10就是对象的up的信息
        const cesiumMatrix4 =
            Cesium.Transforms.eastNorthUpToFixedFrame(cartesian3)
        return Cesium.Matrix4.toArray(cesiumMatrix4).slice(8, 11)
    }

    constructor(camera, domElement) {
        super(camera, domElement)
        this.camera = camera
        this.domElement = domElement
        this.setParameters()
    }
    setParameters(option = {}) {
        // this.enabled = false
        this.maxPolarAngle = Math.PI / 18 *9
        // this.minPolarAngle = Math.PI / 3
        // this.addEventListener('change', render) // call this only in static scenes (i.e., if there is no animation loop)
        // this.enableDamping = true // an animation loop is required when either damping or auto-rotation are enabled
        // this.dampingFactor = 0.05
        // this.screenSpacePanning = false
        // this.minDistance = 1
        // this.maxDistance = Number.MAX_SAFE_INTEGER

        Object.entries(option).forEach(([key, value]) => {
            this[key] = value
        })
        return this
    }

    // todo 下面的localUp是 camera的up 还是目标对象的up？
    //  个人感觉用对象的up向量更合适吧？   因为three.js 原来考虑都是平面。
    // 可能是摄像机和 对象距离 比较近，所以fix时没感觉瞬动。
    fixControls(targetWorldPosition) {

        this.target.fromArray(targetWorldPosition)

        {
            const localUp = new THREE.Vector3().fromArray(
                MyMapControls.getLocalUpFromCartesian(
                    new Cesium.Cartesian3(...targetWorldPosition)
                )
            )

            this.camera.up.copy(localUp)

            this._quat = new THREE.Quaternion().setFromUnitVectors(
                localUp,
                new THREE.Vector3(0, 1, 0)
            )

            this._quatInverse = this._quat.clone().invert()

        }

        this.enabled = true
        this.update()

    }
}
